package cn.mesmile.flow.modules.processinstance.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.mesmile.flow.modules.processinstance.model.dto.StartProcessInstanceDTO;
import cn.mesmile.flow.modules.processinstance.service.ProcessInstanceService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.SubProcess;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author zb
 * @date 2020/12/7 14:13
 * @Description
 */
@AllArgsConstructor
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
@Service
public class ProcessInstanceServiceImpl implements ProcessInstanceService {

    private final RuntimeService runtimeService;

    private final IdentityService identityService;

    private final RepositoryService repositoryService;


    /**
     *
     *      Person person = personRepository.findByUsername(assignee);
     *      启动流程的时候传入一个对象
     *     Map<String, Object> variables = new HashMap<String, Object>();
     *     variables.put("person", person);
     *
     *     flowable:assignee="${person.id}
     *
     * @param startProcessInstanceDTO
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void start(StartProcessInstanceDTO startProcessInstanceDTO) {
        String processDefinitionId = startProcessInstanceDTO.getProcessDefinitionId();
        String businessKey = startProcessInstanceDTO.getBusinessKey();
        Map<String, Object> variables = startProcessInstanceDTO.getVariables();
        // 设置发起人
        identityService.setAuthenticatedUserId("initiatorCode");

        ProcessDefinition holidayRequest = repositoryService
                .createProcessDefinitionQuery().processDefinitionKey("holidayRequest").singleResult();


        ProcessInstance processInstance = runtimeService
                .startProcessInstanceById(processDefinitionId, businessKey, variables);

        System.out.println(">>>>>>>>>>> 启动流程实例成功："+ processInstance.getName());
        System.out.println(">>>>>>>>>>> 启动流程实例成功："+ processInstance.getId());

    }

    @Override
    public void get() {
        Map<String, Object> flowProcess = new HashMap<>();
        runtimeService.createProcessInstanceBuilder()
                .businessKey("1223567")
                .tenantId("租户id")
                .variables(flowProcess)
                .start();


        // 获取流程实例列表
        List<ProcessInstance> list = runtimeService.createProcessInstanceQuery()
                .active().list();
        System.out.println(list);
    }

    @Override
    public void getAllNode() {
        String processInstanceId = "60308c05-ac56-11e9-81d0-dad8d2a12195";
        //获取流程发布Id信息
        String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
        //获取所有节点信息
        List<Process> processes = repositoryService.getBpmnModel(definitionId).getProcesses();
        System.out.println("processes size:" + processes.size());
        List<FlowElement> userTasks = new ArrayList<>();

        // 检查传入搜索的字符串是否为空
        boolean checkResult = StrUtil.isNotEmpty("传入搜索节点名称");

        for (Process process : processes) {
            Collection<FlowElement> flowElements = process.getFlowElements();
            if (CollectionUtil.isNotEmpty(flowElements)) {
                for (FlowElement flowElement : flowElements) {
                    if (flowElement instanceof UserTask) {
                        // 如果不为空，说明需要搜索
                        if (checkResult){
                            //节点名称
                            String nodeName = flowElement.getName();
                            StringUtils.contains("","0");
                            // trim是去除空格
                            boolean contains = StrUtil.contains(nodeName, "传入搜索节点名称".trim());
                            if (contains){
                                userTasks.add(flowElement);
                            }
                        } else {
                            userTasks.add(flowElement);
                        }
                    }
                    if (flowElement instanceof SubProcess) {
                        //，，，
                    }

                }
            }
        }
    }
}
